home *** CD-ROM | disk | FTP | other *** search
- /* setlocale function */
- #include <ctype.h>
- #include <locale.h>
- #include <stdlib.h>
- #include <string.h>
-
-
- #if _NCAT != 6
- #error wrong number of categories
- #endif
- /* static data */
- static char *defname = NULL;<%-2>/* name of "" locale */
- "static int namalloc = 0; /* _Locale._Name allocated */
- static const char * const nmcats[_NCAT] = {
- NULL, "collate:", "ctype:", "monetary:",
- "numeric:", "time:"};
- static struct lconv *pcats[_NCAT] = {NULL};
-
-
- /* set new locale */
- #undef setlocale
- char *setlocale(int cat, const char *lname)
- {
- if (cat < 0 || _NCAT <= cat)
- return (NULL); /* bad category */
- if (lname == NULL)
- return ((char *)_Locale._Name);
- if (lname[0] == '\0')
- { /* find name of default locale */
- char *s1, *s2;
-
-
- if (defname)
- lname = defname;
- else if ((s1 = getenv("LOCALE")) != NULL
- && (s2 = malloc(strlen(s1) + 1)) != NULL)
- lname = defname = strcpy(s2, s1);
- else
- lname = "C";
- }
- if (_Clocale._Ctype == NULL)
- { /* flesh out "C" locale */
- size_t i;
-
-
- for (i = 0; i < _NCAT; ++i)
- pcats[i] = &_Clocale;
- _Clocale._Ctype = _Ctype;
- _Clocale._Tolower = _Tolower;
- _Clocale._Toupper = _Toupper;
- }
- { /* set categories */
- struct lconv *p;
- int changed = 0;
-
-
- if (cat != LC_ALL)
- { /* set a single category */
- if ((p = _Getloc(nmcats[cat], lname)) == NULL)
- return (NULL);
- if (p != pcats[cat])
- pcats[cat] = _Setloc(cat, p), changed = 1;
- }
- else
- { /* set all categories */
- size_t i;
-
-
- for (i = 0; ++i < _NCAT; )
- { /* set a category */
- <%-2>if ((p = _Getloc(nmcats[i], lname)) == NULL)
- " { /* revert all on any failure */
- setlocale(LC_ALL, _Locale._Name);
- return (NULL);
- }
- if (p != pcats[i])
- pcats[i] = _Setloc(i, p), changed = 1;
- }
- if ((p = _Getloc("", lname)) != NULL)
- <%-3>pcats[0] = p; /* set only if LC_ALL
- component */
- " }
- if (changed)
- { /* rebuild _Locale._Name */
- char *s;
- size_t i, n;
- size_t len = strlen(pcats[0]->_Name);
-
- for (i = 0, n = 0; ++i < _NCAT; )
- if (pcats[i] != pcats[0])
- { /* count a changed subcategory */
- len += strlen(nmcats[i])
- + strlen(pcats[i]->_Name) + 1;
- ++n;
- }
- if (n == 1)
- { /* uniform locale */
- if (namalloc)
- free((void *)_Locale._Name);
- _Locale._Name = pcats[1]->_Name;
- namalloc = 0;
- }
- else if ((s = malloc(len + 1)) == NULL)
- { /* may be rash to try to roll back */
- setlocale(LC_ALL, _Locale._Name);
- return (NULL);
- }
- else
- { /* build complex name */
- if (namalloc)
- free((void *)_Locale._Name);
- _Locale._Name = s;
- namalloc = 1;
- s += strlen(strcpy(s, pcats[0]->_Name));
- for (i = 0; ++i < _NCAT; )
-
- if (pcats[i] != pcats[0])
- { /* add a component */
- *s = ';';
- s += strlen(strcpy(s, nmcats[i]));
- <%-4>s += strlen(strcpy(s, pcats[i]->_Name));"
- }
- }
- }
- }
- return ((char *)_Locale._Name);
- }
-
-